package com.szholly.data.general;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.szholly.utils.util.StringUtils;
import com.szholly.utils.util.TreeDataNode;
import com.szholly.data.common.util.TreeDataUtils;

/**
 * 定义非缓存字典域表
 */
public class NoCachedTableDomain implements IDomain {

	private ITable domainTable;
	private String domainName;
	private String domainAliasName;
	private List<TreeDataNode> listEx;
	private HashMap<String, List<TreeDataNode>> nextListEx;

	public NoCachedTableDomain(ITable domainTable, String domainName,
			String domainAliasName) {
		this.domainTable = domainTable;
		this.domainName = domainName;
		this.domainAliasName = domainAliasName;
	}

	@Override
	public String getDomainAliasName() {
		return domainAliasName;
	}

	@Override
	public HashMap<String, String> getDomains() {
		List<RowBase> rowList = getDatas();
		// 分域的代码值，key：域名称， value ：域值
		HashMap<String, String> codes = new HashMap<String, String>();
		// 是唯一值时，直接处理
		for (RowBase itemRow : rowList) {
			String code = (String) itemRow.getValue(GlobalDataType.String,
					this.getCodeFieldName());
			String caption = (String) itemRow.getValue(GlobalDataType.String,
					this.getCaptionFieldName());
			codes.put(code, caption);
		}
		return codes;
	}
	
	private HashMap<String, String[]> codeValuesEx;
	/**
	 * 获取代码值，此值主要用于代码翻译，包括单位的翻译
	 */
	@Override
	public HashMap<String, String[]> getDomainsEx(){
		if(codeValuesEx!=null){
			return codeValuesEx;
		}
		
		if(StringUtils.IsNullOrSpace(this.getUnitFieldName())){
			HashMap<String, String> codeValues = getDomains();
			Set<String> keys = codeValues.keySet();
			codeValuesEx = new HashMap<String, String[]>();
			for(String key : keys){
				String[] value = new String[2];
				value[0] = codeValues.get(key);
				codeValuesEx.put(key, value);
			}
			return codeValuesEx;
		}else{
			codeValuesEx = new HashMap<String, String[]>();
			List<RowBase> codeValues = getDatas();
			for(RowBase row : codeValues){
				String code = (String)row.getValue(GlobalDataType.String, this.getCodeFieldName());
				String caption = (String)row.getValue(GlobalDataType.String, this.getCaptionFieldName());
				String unit = (String)row.getValue(GlobalDataType.String, this.getUnitFieldName());
				
				String[] value = new String[2];
				value[0] = caption;
				value[1] = unit;
				codeValuesEx.put(code, value);
			}
			return codeValuesEx;
		}
	}

	@Override
	public List<RowBase> getDatas() {
		IQueryMap queryMap = new QueryMap();
		if (!StringUtils.IsNullOrEmpty(domainName)) {
			queryMap.getWhereMap().put(this.getDomainFieldName(), domainName);
			queryMap.getOrderByMap().put(this.getDomainFieldName(), 1);
		}
		if(StringUtils.IsNullOrSpace(getOrderFieldName())){
			queryMap.getOrderByMap().put(getCodeFieldName(), 1);
		}else{
			queryMap.getOrderByMap().put(getOrderFieldName(), 1);
		}
		queryMap.setSelectFields(getSelectedFields());
		
		return domainTable.getEntityList(RowBase.class, queryMap);
	}
	
	private String getSelectedFields(){
		String selectedField = "";
		if(!StringUtils.IsNullOrSpace(this.getCaptionFieldName())){
			selectedField += this.getCaptionFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getCodeFieldName())){
			selectedField += this.getCodeFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getDomainFieldName())){
			selectedField += this.getDomainFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getIDFieldName())){
			selectedField += this.getIDFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getIsChildFieldName())){
			selectedField += this.getIsChildFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getIsEditFieldName())){
			selectedField += this.getIsEditFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getIsUsedFieldName())){
			selectedField += this.getIsUsedFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getLevelFieldName())){
			selectedField += this.getLevelFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getOrderFieldName())){
			selectedField += this.getOrderFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getPIDFieldName())){
			selectedField += this.getPIDFieldName() + ",";
		}
		if(!StringUtils.IsNullOrSpace(this.getUnitFieldName())){
			selectedField += this.getUnitFieldName() + ",";
		}
		if(selectedField!=""){
			selectedField = selectedField.substring(0, selectedField.length()-1);
		}
		return selectedField;
	}

	public HashMap<String, String> getDomains(String codes) {
		List<RowBase> rowList = getDatas(codes);
		// 分域的代码值，key：域名称， value ：域值
		HashMap<String, String> codeList = new HashMap<String, String>();
		// 是唯一值时，直接处理
		for (RowBase itemRow : rowList) {
			String code = (String) itemRow.getValue(GlobalDataType.String,
					this.getCodeFieldName());
			String caption = (String) itemRow.getValue(GlobalDataType.String,
					this.getCaptionFieldName());
			codeList.put(code, caption);
		}
		return codeList;
	}

	public List<RowBase> getDatas(String codes) {
		IQueryMap queryMap = new QueryMap();
		if (!StringUtils.IsNullOrEmpty(domainName)) {
			queryMap.getWhereMap().put(this.getDomainFieldName(), domainName);
			queryMap.getOrderByMap().put(this.getDomainFieldName(), 1);
		}
		queryMap.getOrderByMap().put(this.getCodeFieldName(), 1);
		queryMap.getWhereMap().put(this.getCodeFieldName() + ":in", codes);
		return domainTable.getEntityList(RowBase.class, queryMap);
	}
	
	public List<RowBase> getDatas(HashMap<String, Object> filterMap) {
		IQueryMap queryMap = new QueryMap();
		if (!StringUtils.IsNullOrEmpty(domainName)) {
			queryMap.getWhereMap().put(this.getDomainFieldName(), domainName);
			queryMap.getOrderByMap().put(this.getDomainFieldName(), 1);
		}
		queryMap.getOrderByMap().put(this.getCodeFieldName(), 1);
		queryMap.getWhereMap().putAll(filterMap);
		return domainTable.getEntityList(RowBase.class, queryMap);
	}

	@Override
	public List<TreeDataNode> getDatasEx() {

		List<RowBase> rowList = getDatas();
		if (rowList == null) {
			return null;
		}
		listEx = TreeDataUtils.GetTreeData(rowList, this.getIDFieldName(),
				this.getPIDFieldName(), this.getCodeFieldName(),
				this.getCaptionFieldName());

		if (listEx == null) {
			listEx = new ArrayList<TreeDataNode>();
		}

		List<TreeDataNode> result = new ArrayList<TreeDataNode>();
		result.addAll(listEx);
		return result;
	}
	@Override
	public List<TreeDataNode> getDatasEx(HashMap<String, Object> filterMap,String extKey,String extVal) {
		//TODO 带政区ID的字典过滤
		return null;
	}
	@Override
	public List<TreeDataNode> getDatasEx(HashMap<String, Object> filterMap) {
		List<RowBase> rowList = getDatas(filterMap);
		if (rowList == null) {
			return null;
		}
		List<TreeDataNode> result = new ArrayList<TreeDataNode>();
		result = TreeDataUtils.GetTreeData(rowList, this.getIDFieldName(),
				this.getPIDFieldName(), this.getCodeFieldName(),
				this.getCaptionFieldName());
		return result;
	}
	
	/**
	 * 按过滤条件过滤数据
	 * @param result
	 * @param filterMap
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unused" })
	private List<TreeDataNode> filterResult(List<TreeDataNode> result, HashMap<String, Object> filterMap){
		List<TreeDataNode> filterResult = new ArrayList<TreeDataNode>();
		for (int i = 0; i < result.size(); i++) {
			TreeDataNode node = result.get(i);
			RowBase row = (RowBase)node.getAttributes();
			Set keyArray =  filterMap.keySet();
			Iterator iterator = keyArray.iterator();
			while (iterator.hasNext()) {
				String key = iterator.next().toString();
				String rowValue = (String) row.getValue(key);
				String value = (String) filterMap.get(key);
				if (!StringUtils.IsNullOrSpace(rowValue) && rowValue.equals(value)) {
					filterResult.add(node);
				}
			}
		}
		return filterResult;
	}

	private List<Map<String, Object>> listEx2 = null;

	/**
	 * 获取所有数据，并转换成可绑定到TreeGrid的数据对象
	 * 
	 * @return
	 */
	@Override
	public List<Map<String, Object>> getDatasEx2(boolean convertStaticField) {
		if (listEx2 != null) {
			List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
			result.addAll(listEx2);
			return result;
		}

		List<RowBase> rowList = getDatas();
		if (rowList == null) {
			return null;
		}

		listEx2 = TreeDataUtils.GetTreeData(rowList, getIDFieldName(), getPIDFieldName(),
				getIsChildFieldName(), getCodeFieldName(),
				getCaptionFieldName());

		if (convertStaticField) {
			CachedTableDomain.convertStaticField(listEx2, this);
		}

		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		if (listEx2 == null) {
			listEx2 = new ArrayList<Map<String, Object>>();
		}
		result.addAll(listEx2);
		return result;
	}

	@Override
	public List<RowBase> getNextDatas(String id) {
		return null;
	}

	@Override
	public List<TreeDataNode> getNextDatasEx(String id) {
		if (nextListEx != null && nextListEx.containsKey(id)) {
			List<TreeDataNode> list = nextListEx.get(id);

			List<TreeDataNode> result = new ArrayList<TreeDataNode>();
			result.addAll(list);
			return result;
		}

		List<RowBase> rowList = getNextDatas(id);
		if (rowList == null) {
			return null;
		}
		List<TreeDataNode> list = TreeDataUtils.GetTreeData(rowList,
				this.getIDFieldName(), this.getPIDFieldName(),
				this.getCodeFieldName(), this.getCaptionFieldName());
		if (nextListEx == null) {
			nextListEx = new HashMap<String, List<TreeDataNode>>();
		}
		nextListEx.put(id, list);

		List<TreeDataNode> result = new ArrayList<TreeDataNode>();
		result.addAll(list);
		return result;
	}

	@Override
	public Boolean getIsTreeCode() {
		return getCodeTable().getIsTreeTable();
	}

	@Override
	public ITable getCodeTable() {
		return domainTable;
	}

	@Override
	public String getIDFieldName() {
		return getCodeTable().getIDFieldName();
	}

	@Override
	public String getPIDFieldName() {
		return getCodeTable().getPIDFieldName();
	}

	@Override
	public String getCodeFieldName() {
		return getCodeTable().getCodeFieldName();
	}

	@Override
	public String getCaptionFieldName() {
		return getCodeTable().getCaptionFieldName();
	}

	@Override
	public boolean getIsManageCodeTable() {
		return getCodeTable().getIsManageCodeTable();
	}

	@Override
	public String getOrderFieldName() {
		return getCodeTable().getOrderFieldName();
	}

	@Override
	public String getIsUsedFieldName() {
		return getCodeTable().getIsUsedFieldName();
	}

	@Override
	public String getIsEditFieldName() {
		return getCodeTable().getIsEditFieldName();
	}
	
	/**
	 * 获取单位字段
	 */
	@Override
	public String getUnitFieldName(){
		return getCodeTable().getUnitFieldName();
	}

	@Override
	public String getLevelFieldName() {
		return getCodeTable().getLevelFieldName();
	}

	@Override
	public String getDomainFieldName() {
		return getCodeTable().getDomainFieldName();
	}

	@Override
	public String getIsChildFieldName() {
		return getCodeTable().getIsChildFieldName();
	}
}
